package com.apikey.auth.validator;

import java.util.List;
import java.util.Set;

/**
 * API Key权限验证器接口
 * 用于验证API Key的权限，支持扩展自定义权限验证逻辑
 *
 * @author API Key Framework
 * @version 1.0
 */
public interface ApiKeyPermissionValidator {

    /**
     * 验证API Key是否有访问指定资源的权限
     *
     * @param apiKeyValue API Key值
     * @param resource    资源标识
     * @param action      操作类型（如：READ, WRITE, DELETE等）
     * @return 是否有权限
     */
    boolean hasPermission(String apiKeyValue, String resource, String action);

    /**
     * 验证API Key是否有访问指定路径的权限
     *
     * @param apiKeyValue API Key值
     * @param requestPath 请求路径
     * @param httpMethod  HTTP方法
     * @return 是否有权限
     */
    boolean hasPathPermission(String apiKeyValue, String requestPath, String httpMethod);

    /**
     * 获取API Key的所有权限列表
     *
     * @param apiKeyValue API Key值
     * @return 权限列表
     */
    List<String> getPermissions(String apiKeyValue);

    /**
     * 获取API Key可访问的资源列表
     *
     * @param apiKeyValue API Key值
     * @return 可访问的资源集合
     */
    Set<String> getAccessibleResources(String apiKeyValue);

    /**
     * 验证权限字符串格式是否正确
     *
     * @param permissions 权限字符串（逗号分隔）
     * @return 是否格式正确
     */
    boolean isValidPermissionFormat(String permissions);

    /**
     * 解析权限字符串为权限列表
     *
     * @param permissions 权限字符串（逗号分隔）
     * @return 权限列表
     */
    List<String> parsePermissions(String permissions);

    /**
     * 将权限列表转换为权限字符串
     *
     * @param permissions 权限列表
     * @return 权限字符串（逗号分隔）
     */
    String formatPermissions(List<String> permissions);

    /**
     * 验证权限是否存在于系统中
     *
     * @param permission 权限标识
     * @return 权限是否存在
     */
    boolean isValidPermission(String permission);

    /**
     * 获取所有可用的权限列表
     *
     * @return 所有可用权限列表
     */
    List<String> getAllAvailablePermissions();

    /**
     * 获取权限的描述信息
     *
     * @param permission 权限标识
     * @return 权限描述
     */
    String getPermissionDescription(String permission);

    /**
     * 验证用户是否有权限分配指定的权限给API Key
     *
     * @param userId      用户ID
     * @param permissions 要分配的权限列表
     * @return 是否有权限分配
     */
    boolean canAssignPermissions(String userId, List<String> permissions);

    /**
     * 获取用户可以分配的权限列表
     *
     * @param userId 用户ID
     * @return 可分配的权限列表
     */
    List<String> getAssignablePermissions(String userId);

    /**
     * 权限验证结果
     */
    class PermissionResult {
        private boolean allowed;
        private String reason;
        private List<String> requiredPermissions;

        /**
         * 默认构造函数
         */
        public PermissionResult() {
        }

        /**
         * 构造函数
         *
         * @param allowed 是否允许
         * @param reason  原因
         */
        public PermissionResult(boolean allowed, String reason) {
            this.allowed = allowed;
            this.reason = reason;
        }

        /**
         * 构造函数
         *
         * @param allowed             是否允许
         * @param reason              原因
         * @param requiredPermissions 所需权限列表
         */
        public PermissionResult(boolean allowed, String reason, List<String> requiredPermissions) {
            this.allowed = allowed;
            this.reason = reason;
            this.requiredPermissions = requiredPermissions;
        }

        /**
         * 创建允许的结果
         *
         * @return 允许的结果
         */
        public static PermissionResult allow() {
            return new PermissionResult(true, "权限验证通过");
        }

        /**
         * 创建拒绝的结果
         *
         * @param reason 拒绝原因
         * @return 拒绝的结果
         */
        public static PermissionResult deny(String reason) {
            return new PermissionResult(false, reason);
        }

        /**
         * 创建拒绝的结果（包含所需权限）
         *
         * @param reason              拒绝原因
         * @param requiredPermissions 所需权限列表
         * @return 拒绝的结果
         */
        public static PermissionResult deny(String reason, List<String> requiredPermissions) {
            return new PermissionResult(false, reason, requiredPermissions);
        }

        // Getter和Setter方法

        public boolean isAllowed() {
            return allowed;
        }

        public void setAllowed(boolean allowed) {
            this.allowed = allowed;
        }

        public String getReason() {
            return reason;
        }

        public void setReason(String reason) {
            this.reason = reason;
        }

        public List<String> getRequiredPermissions() {
            return requiredPermissions;
        }

        public void setRequiredPermissions(List<String> requiredPermissions) {
            this.requiredPermissions = requiredPermissions;
        }

        @Override
        public String toString() {
            return "PermissionResult{" +
                    "allowed=" + allowed +
                    ", reason='" + reason + '\'' +
                    ", requiredPermissions=" + requiredPermissions +
                    '}';
        }
    }
}